import { Service } from 'egg';
import { createSSRApp } from 'vue';
import legoComponents from 'lego-components';
import { renderToString } from '@vue/server-renderer';

function propsToStyle(props = {}) {
  const keys = Object.keys(props);
  const styleArr = keys.map((key) => {
    const formatKey = key.replace(/[A-Z]/g, (c) => `-${c.toLocaleLowerCase()}`);
    const value = props[key];
    return `${formatKey}: ${value}`;
  });
  return styleArr.join(';');
}

function px2vw(components = []) {
  const reg = /^(\d+(\.\d+)?)px$/;
  components.forEach((component: any = {}) => {
    const props = component.props || {};
    Object.keys(props).forEach((key) => {
      const val = props[key];
      if (typeof val !== 'string') {
        return;
      }
      if (reg.test(val) === false) {
        return false;
      }
      const arr = val.match(reg) || [];
      const numStr = arr[1];
      const num = parseFloat(numStr);
      const vwNum = (num / 375) * 100;
      props[key] = `${vwNum.toFixed(2)}vw`;
    });
  });
}

export default class UtilService extends Service {
  async renderToPageData(query: { id: number; uuid: string }) {
    const work = await this.ctx.model.Work.findOne(query).lean();
    if (!work) {
      throw new Error('work not exsit');
    }
    const { title, desc, content } = work;
    px2vw(content && content.components);
    const vueApp = createSSRApp({
      data: () => {
        return {
          components: (content && content.components) || [],
        };
      },
      template: '<final-page :components="components"></final-page>',
    });
    vueApp.use(legoComponents);
    const html = await renderToString(vueApp);
    const bodyStyle = propsToStyle(content && content.props);
    return {
      html,
      title,
      desc,
      bodyStyle,
    };
  }
}
